﻿#region Includes
using System;
using OpenTK;
#endregion

namespace GingerGL
{
    //------------------------------------------------------------//
    /// <summary>
    /// Force of an Object
    /// </summary>
    public class Force
    {
        //--------------------------------------------------------//
        #region Variables
        private Vector3 mAcceleration;
        private Vector3 mDirection;
        private Vector3 mMaxVelocity;
        private Vector3 mMinVelocity;
        private Vector3 mVelocity;
        #endregion
        //--------------------------------------------------------//
        #region Properties
        /// <summary>
        /// Acceleration Vector
        /// </summary>
        public Vector3 Acceleration { get { return mAcceleration; } protected set { mAcceleration = value; } }
        /// <summary>
        /// Direction
        /// </summary>
        public Vector3 Direction { get { return mDirection; } protected set { mDirection = value; } }
        /// <summary>
        /// Maxium Velocity
        /// </summary>
        public Vector3 MaxVelocity { get { return mMaxVelocity; } protected set { mMaxVelocity = value; } }
        /// <summary>
        /// Minimum Velocity
        /// </summary>
        public Vector3 MinVelocity { get { return mMinVelocity; } protected set { mMinVelocity = value; } }
        /// <summary>
        /// Current Velocity
        /// </summary>
        public Vector3 Velocity { get { return mVelocity; } protected set { mVelocity = value; } }
        #endregion
        //--------------------------------------------------------//
        #region Methods
        /// <summary>
        /// Adds Velocity to X 
        /// </summary>
        public void AddVelocityX(float X)
        {
            this.mVelocity.X += X;
            if (this.mVelocity.X > this.mMaxVelocity.X) this.mVelocity.X = this.mMaxVelocity.X;
            if (this.mVelocity.X < this.mMinVelocity.X) this.mVelocity.X = this.mMinVelocity.X;
        }
        /// <summary>
        /// Add Velocity to Y
        /// </summary>
        public void AddVelocityY(float Y)
        {
            this.mVelocity.Y += Y;
            if (this.mVelocity.Y > this.mMaxVelocity.Y) this.mVelocity.Y = this.mMaxVelocity.Y;
            if (this.mVelocity.Y < this.mMinVelocity.Y) this.mVelocity.Y = this.mMinVelocity.Y;
        }
        /// <summary>
        /// Add Velocity to z
        /// </summary>
        public void AddVelocityZ(float Z)
        {
            this.mVelocity.Z += Z;
            if (this.mVelocity.Z > this.mMaxVelocity.Z) this.mVelocity.Z = this.mMaxVelocity.Z;
            if (this.mVelocity.Z < this.mMinVelocity.Z) this.mVelocity.Z = this.mMinVelocity.Z;
        }
        /// <summary>
        /// Set Velocity
        /// </summary>
        public void SetVelocity(float X, float Y, float Z)
        {
            this.mVelocity.X = 0; this.AddVelocityX(X);
            this.mVelocity.Y = 0; this.AddVelocityY(Y);
            this.mVelocity.Z = 0; this.AddVelocityZ(Z);
        }
        /// <summary>
        /// Update Force based on Time
        /// </summary>
        public void Update(Vector3 SourcePoint, float TimeElapsed)
        {
            this.mVelocity.X += this.mAcceleration.X * (TimeElapsed * TimeElapsed);
            this.mVelocity.Y += this.mAcceleration.Y * (TimeElapsed * TimeElapsed);
            this.mVelocity.Z += this.mAcceleration.Z * (TimeElapsed * TimeElapsed);

            if (this.mVelocity.X > this.mMaxVelocity.X) this.mVelocity.X = this.mMaxVelocity.X;
            if (this.mVelocity.Y > this.mMaxVelocity.Y) this.mVelocity.Y = this.mMaxVelocity.Y;
            if (this.mVelocity.Z > this.mMaxVelocity.Z) this.mVelocity.Z = this.mMaxVelocity.Z;
            if (this.mVelocity.X < this.mMinVelocity.X) this.mVelocity.X = this.mMinVelocity.X;
            if (this.mVelocity.Y < this.mMinVelocity.Y) this.mVelocity.Y = this.mMinVelocity.Y;
            if (this.mVelocity.Z < this.mMinVelocity.Z) this.mVelocity.Z = this.mMinVelocity.Z;

            SourcePoint.X += (this.mDirection.X * this.mVelocity.X) * TimeElapsed;
            SourcePoint.Y += (this.mDirection.Y * this.mVelocity.Y) * TimeElapsed;
            SourcePoint.Z += (this.mDirection.Z * this.mVelocity.Z) * TimeElapsed;
        }
        #endregion
        //--------------------------------------------------------//
    }
    //------------------------------------------------------------//
}
